package com.kajespero.jdo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jdo.Query;

import org.apache.commons.lang.StringUtils;

import com.kajespero.utils.PersistManagerJdoHelper;

public class Criteria<T extends Serializable> implements ICritereria {

	/**
	 * 
	 */
	private static final long serialVersionUID = -2403561069647783507L;

	private Map<String, String> mapOrder;

	private Map<String, Object> mapProperties;
	
	private Class<T> clazz;
	
	public Criteria(Class<T> clazz){
		this.clazz = clazz;
		this.mapOrder = new HashMap<String, String>();
		this.mapProperties = new HashMap<String, Object>();
		
	}

	@Override
	public void addOrder(String prop, String order) {
		this.mapOrder.put(prop, order);
	}

	@Override
	public void addProperty(String prop, Object value) {
		this.mapProperties.put(prop, value);
	}

	@Override
	public Collection<Object> getValues() {
		return this.mapProperties.values();
	}

	@Override
	public Collection<String> getProperties() {
		return this.mapProperties.keySet();
	}

	@Override
	public Collection<String> getOrders() {
		List<String> orders = new ArrayList<String>();
		for(String key : mapOrder.keySet()){
			String ordering = key + " " + mapOrder.get(key);
			orders.add(ordering);
		}
		return orders;
	}

	@Override
	public Collection<String> getFilters() {
		List<String> filters = new ArrayList<String>();
		for(String key : mapProperties.keySet()){
			String filter = key + " == :" + key;
			filters.add(filter);
		}
		return filters;
	}

	@Override
	public Collection<String> getDeclararedParameters() {
		List<String> declaredParams = new ArrayList<String>();
		for(String key : mapProperties.keySet()){
			Object obj = mapProperties.get(key);
			String param = obj.getClass().getSimpleName() + " " + key;
			declaredParams.add(param);
		}
		return declaredParams;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection<T> executeCriteria() {
		Query query = PersistManagerJdoHelper.getPersistenceManager().newQuery(this.clazz);
		// filters
		List<String> temp = (List<String>) getFilters();
		if(temp != null && !temp.isEmpty() ){
			query.setFilter(StringUtils.join(temp, "&&"));
		}
		// orders
		temp = null;
		temp = (List<String>) getOrders();
		if(temp != null && !temp.isEmpty() ){
			query.setOrdering(StringUtils.join(temp, ","));
		}
		List<T> list = new ArrayList<T>();
		list.addAll((Collection<? extends T>) query.executeWithMap(mapProperties));
		query.closeAll();
		return list;
	}


	@Override
	public Query createQuery() {
		Query query = PersistManagerJdoHelper.getPersistenceManager().newQuery(this.clazz);
		return query;
	}
	
	
}
